﻿using System.Collections.Generic;
using USClientKernel.Template;

namespace Common.Utils
{
    public delegate void EventHandler(BaseEvent _event);

    public class BaseEvent
    {
        public int EventType { set; get; }
        public object[] Args { set; get; }

        public virtual T Cast<T>() where T : BaseEvent
        {
            return this as T;
        }
    }

    public class Subscriber
    {
        private EventHandler m_handlerEvent;
        public uint RefCount { private set; get; }

        Subscriber(EventHandler _handler)
        {
            m_handlerEvent = _handler;
        }

        public static Subscriber Create(int _eventType, EventHandler _handler)
        {
            Subscriber s = new Subscriber(_handler);
            s.Subscrib(_eventType);
            return s;
        }

        public bool Subscrib(int _eventType)
        {
            bool r = EventManager.Instance.Subscrib(_eventType, this);
            if (r) RefCount++;
            return r;
        }

        public bool Unsubscrib(int _eventType)
        {
            bool r = EventManager.Instance.Subscrib(_eventType, this);
            if (r) RefCount--;
            return r;
        }

        public void UnsubscribAll()
        {
            RefCount = 0;
            EventManager.Instance.UnsubscribAll(this);
        }

        public void HandleEvent(BaseEvent _event)
        {
            if (null != m_handlerEvent)
            {
                m_handlerEvent.Invoke(_event);
            }
        }
    }

    public class Publisher
    {
        public static void Publish(BaseEvent _event)
        {
            EventManager.Instance.Publish(_event);
        }
    }

    public class EventManager : Singleton<EventManager>
    {
        // 订阅者列表
        private Dictionary<int, List<Subscriber>> m_dictSubscriberList;


        // 初始化
        protected override void Init()
        {
            m_dictSubscriberList = new Dictionary<int, List<Subscriber>>();
        }


        // 开始订阅
        public bool Subscrib(int _eventType, Subscriber _subscriber)
        {
            if (!m_dictSubscriberList.TryGetValue(_eventType, out List<Subscriber> subscriberList))
            {
                subscriberList = new List<Subscriber>();
                m_dictSubscriberList.Add(_eventType, subscriberList);
            }

            if (!subscriberList.Contains(_subscriber))
            {
                subscriberList.Add(_subscriber);
                return true;
            }
            else
            {
                return false;
            }
        }


        // 取消订阅
        public bool Unsubscrib(int _eventType, Subscriber _subscriber)
        {
            if (!m_dictSubscriberList.TryGetValue(_eventType, out List<Subscriber> subscriberList))
            {
                return false;
            }

            if (subscriberList.Contains(_subscriber))
            {
                subscriberList.Remove(_subscriber);
                return true;
            }
            else
            {
                return false;
            }
        }


        // 取消全部订阅
        public void UnsubscribAll(Subscriber _subscriber)
        {
            foreach (List<Subscriber> subscriberList in m_dictSubscriberList.Values)
            {
                if (subscriberList.Contains(_subscriber))
                {
                    subscriberList.Remove(_subscriber);
                }
            }
        }


        // 发布事件
        public void Publish(BaseEvent _event)
        {
            if (!m_dictSubscriberList.TryGetValue(_event.EventType, out List<Subscriber> subscriberList))
            {
                return;
            }

            foreach (Subscriber s in subscriberList)
            {
                s.HandleEvent(_event);
            }         
        }
    }
}
